package per.qiao.simplerest.core;

import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import per.qiao.simplerest.components.actuator.RestTemplateActuator;
import per.qiao.simplerest.components.resttemplate.HttpClientRestFactoryComponents;
import per.qiao.simplerest.components.resttemplate.OkHttp3ClientHttpRequestFactoryComponents;
import per.qiao.simplerest.components.resttemplate.RestTemplateComponents;
import per.qiao.simplerest.restargument.DefulatArgumentResolver;
import per.qiao.simplerest.restresolver.RestAutoConfigBean;
import per.qiao.simplerest.returenvalue.DefaultValueHandler;

/**
 * Company: 上海数惠系统技术有限公司
 * Department: 数据中心
 * Date: 2020-05-30 13:40
 *
 * @Author: qyp
 * Email: qiaoyp@dist.com.cn
 * Desc: @Configuration注解必须加上，不然本类中的@Bean方法不会生效
 */
//@ConditionalOnProperty(prefix = "rest.service", name = "use", havingValue = "true")
@Configuration
@ConditionalOnExpression(value = "${rest.service.enabled}")
@EnableConfigurationProperties(RestAutoConfigBean.class)
public class RestServiceAutoConfig extends RestServiceSupportDelegate {


    /*@Bean
    RestMappingScanner restMappingScanner() {
        RestMappingScanner restMappingScanner = new RestMappingScanner();
        return restMappingScanner;
    }


    @Bean
    RestServiceScanner restServiceScanner() {
        RestServiceScanner restServiceScanner = new RestServiceScanner();
        return restServiceScanner;
    }*/

    @Bean
    DefulatArgumentResolver defulatArgumentResolver() {
        return new DefulatArgumentResolver();
    }

    @Bean
    DefaultValueHandler defaultValueHandler() {
        return new DefaultValueHandler();
    }

    @Configuration
    @ConditionalOnProperty(prefix = "rest.service.restTemplateComponent", name = "enabled", havingValue = "true", matchIfMissing = true)
    public static class RestTemplateService {

        /**
         * 默认启用的
         * @return
         */
        @ConditionalOnProperty(prefix = "rest.service.restTemplateComponent", name = "requestFactory", havingValue = "okHttp", matchIfMissing = true)
        @Bean
        OkHttp3ClientHttpRequestFactoryComponents okHttp3ClientHttpRequestFactoryComponents() {
            return new OkHttp3ClientHttpRequestFactoryComponents();
        }

        @ConditionalOnMissingBean(RestTemplateComponents.class)
        @ConditionalOnProperty(prefix = "rest.service.restTemplateComponent", name = "requestFactory", havingValue = "httpClient")
        @Bean
        HttpClientRestFactoryComponents httpClientRestFactoryComponents() {
            return new HttpClientRestFactoryComponents();
        }

        @ConditionalOnBean(RestTemplateComponents.class)
        @Bean
        protected RestTemplate getRestTemplate(RestTemplateComponents restTemplateComponents, RestAutoConfigBean restAutoConfigBean) {
            ClientHttpRequestFactory clientHttpRequestFactory;
            RestAutoConfigBean.RestTemplateComponent restTemplateComponent = restAutoConfigBean.getRestTemplateComponent();
            if (restTemplateComponent.isCacheResult()) {
                clientHttpRequestFactory = new BufferingClientHttpRequestFactory(restTemplateComponents.getClientHttpRequestFactory());
            } else {
                clientHttpRequestFactory = restTemplateComponents.getClientHttpRequestFactory();
            }

            RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
            restTemplate.setInterceptors(restTemplateComponents.getClientHttpRequestInterceptor());
            return restTemplate;
        }

        /**
         * 执行器
         */
        @Bean
        RestTemplateActuator restTemplateActuator(RestTemplateComponents restTemplateComponents) {
            return new RestTemplateActuator(restTemplateComponents);
        }
    }

}
